#region Using's

using System;
using System.Collections.Generic;
using System.Linq;
using LightPersist.Exceptions;
using LightPersist.Metainfo;

#endregion

namespace LightPersist
{
	public class ObjectState
	{
		readonly Dictionary<string, ValueState> _propertyNameToStateMap = new Dictionary<string, ValueState>();

		#region Property

		ClassMetainfo _classMetainfo;

//		/// <summary>
//		/// Incremented evry commit
//		/// Compared with same value in storrage
//		/// Managed by _context, not by storrage
//		/// </summary>
//		public int Version { get; set; }

		public Guid Identity { get; set; }

		public LightPersistContext LightPersistContext
		{
			get
			{
				return (LightPersistContext)_lightPersistContext.Target;
			}
		}

		readonly WeakReference _lightPersistContext;

		public ObjectState()
		{
			
		}

		public ObjectState(LightPersistContext lightPersistContext)
		{
			_lightPersistContext = new WeakReference(lightPersistContext);
		}

		public ClassMetainfo ClassMetainfo
		{
			get { return _classMetainfo; }
			set
			{
				if (value == null)
				{
					throw new LightPersistException("ClassMetainfo can not be null");
				}
				_classMetainfo = value;
			}
		}

		public string ClassMetainfoDetected { set; get; }

		public IEnumerable<KeyValuePair<string, object>> PropertiesState
		{
			get { return _propertyNameToStateMap.Select(x => new KeyValuePair<string, object>(x.Key, x.Value.Value)); }
		}

		#endregion

		public FieldState GetPropertyState(object target, string name)
		{
			return FieldState.NotLoaded;
		}

		public void ClearObject()
		{
			_propertyNameToStateMap.Clear();
		}

		public object Get(string name)
		{
			ValueState val;
			var result = !_propertyNameToStateMap.TryGetValue(name, out val) ? null : (val == null ? null : val.Value);
			//if(name == ModelBase.StrongBackReferenceListName || name == ModelBase.WeakBackReferenceListName)
			//{
			//	Debug.AssertExists(result);
			//}
			return result;
		}

		public void Set(string name, object value)
		{
			if (name == ModelBase.StrongBackReferenceListName || name == ModelBase.WeakBackReferenceListName)
			{
				Debug.AssertExists(value);
			}

			ValueState state;
			if (!_propertyNameToStateMap.TryGetValue(name, out state))
			{
				state = new ValueState();
				_propertyNameToStateMap.Add(name, state);
			}

			state.Value = value;
		}
	}
}